package com.tensai.other.zd.screen;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RuntimeUtil;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.win32.StdCallLibrary;
import reactor.util.function.Tuple4;
import reactor.util.function.Tuples;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

public class SwitchScreen {
    public interface User32 extends StdCallLibrary {
        User32 INSTANCE = Native.load("user32", User32.class);

        boolean EnumWindows(WinUser.WNDENUMPROC lpEnumFunc, Pointer arg);

        int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount);

        boolean SetForegroundWindow(HWND hWnd);

        boolean ShowWindow(HWND hWnd, int nCmdShow);
    }

    public static void main(String[] args) {

        HWND hwnd = getHandler(args[0]);
        boolean a = User32.INSTANCE.ShowWindow(hwnd, 1);
        System.out.println(a);
        boolean b = User32.INSTANCE.SetForegroundWindow(hwnd);
        System.out.println(b);
    }

    private static HWND getHandler(String title) {
        AtomicReference<HWND> hwnd0 = new AtomicReference<>();
        User32.INSTANCE.EnumWindows((hwnd, pointer) -> {
            byte[] windowText = new byte[512];
            User32.INSTANCE.GetWindowTextA(hwnd, windowText, 512);
            String wText = Native.toString(windowText);
            customLogic().accept(Tuples.of(wText, title, hwnd0, hwnd));
            return true;
        }, null);
        return hwnd0.get();
    }

    public static Consumer<Tuple4<String, String, AtomicReference<HWND>, HWND>> customLogic() {
        return tp4 -> {
            if (!tp4.getT1().isEmpty() && tp4.getT1().contains(tp4.getT2())) {
                tp4.getT3().set(tp4.getT4());
            }
        };
    }


    public void init() {
        RuntimeUtil.execForStr("start aaa.bat");
        ThreadUtil.execute(() -> {
            Set<String> set = new HashSet<String>() {{
                add("OPLPage");
                add("SPLPage");
            }};
            Map<String, HWND> map = getHandler(set);
            int i = 0;
            while (map.keySet().size() < 2 && i < 10) {
                map = getHandler(set);
                i++;
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
            HWND hwnd = map.get("OPLPage");
            User32.INSTANCE.ShowWindow(hwnd, 1);
            User32.INSTANCE.SetForegroundWindow(hwnd);
        });

    }

    private static Map<String, HWND> getHandler(Set<String> set) {
        Map<String, HWND> map = new HashMap<>();
        User32.INSTANCE.EnumWindows((hwnd, pointer) -> {
            byte[] windowText = new byte[512];
            User32.INSTANCE.GetWindowTextA(hwnd, windowText, 512);
            String wText = Native.toString(windowText);
            if (wText.isEmpty()) {
                return true;
            }
            set.forEach(it -> {
                if (wText.contains(it)) {
                    map.put(it, hwnd);
                    System.out.println("Found window with text " + hwnd + ", total " + " Text: " + wText);
                }
            });
            return true;
        }, null);
        return map;
    }


}
